package com.sz.biz.logistics.base.service.impl;

import com.sz.biz.common.constants.ErrorCodes;
import com.sz.biz.common.constants.ModuleNames;
import com.sz.biz.logistics.base.dto.PortDto;
import com.sz.biz.logistics.base.dto.ShippingLineDetailDto;
import com.sz.biz.logistics.base.dto.ShippingLineDto;
import com.sz.biz.logistics.base.service.PortService;
import com.sz.biz.logistics.base.service.ShippingLineDetailService;
import com.sz.biz.logistics.base.service.ShippingLineService;
import com.sz.biz.logistics.base.entity.Port;
import com.sz.biz.logistics.base.entity.ShippingLine;
import com.sz.biz.logistics.base.entity.ShippingLineDetail;
import com.sz.common.base.constants.UserActions;
import com.sz.common.base.dao.DaoSupport;
import com.sz.common.base.dao.ParamData;
import com.sz.common.base.dto.QResultDto;
import com.sz.common.base.dto.QueryParams;
import com.sz.common.base.dto.ResultDto;
import com.sz.common.base.exception.Exceptions;
import com.sz.common.base.service.AbstractService;
import com.sz.common.base.utils.CollectionUtils;
import com.sz.common.base.utils.EntityUtils;
import com.sz.common.base.utils.StringUtils;
import com.sz.common.core.service.PrincipalLogUtils;
import com.sz.common.core.service.PrincipalUtils;
import com.sz.common.core.system.service.SysDictService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Function: 海运航线ShippingLineServiceImpl <br>
 * Author: wentao.chang <br>
 * Date: 2017-08-04 15:41:00
 */
@Service("shippingLineService")
@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
public class ShippingLineServiceImpl extends AbstractService implements ShippingLineService {

    @Resource(name = "daoSupport")
    private DaoSupport dao;

    @Autowired
    private PortService portService;
    @Autowired
    private SysDictService sysDicttService;
    @Autowired
    private ShippingLineDetailService shippingLineDetailService;

    @Override
    public int save(ShippingLineDto shippingLineDto) {
        ShippingLine shippingLine = new ShippingLine();
        EntityUtils.copyPropertiesIgnoreNull(shippingLineDto, shippingLine);
        // 检查数据不能重复
        ///checkName(shippingLine.getName(), null);
        checkCode(shippingLine.getCode(), null);
        shippingLine.setCreateUserId(PrincipalUtils.getAccountId());
        shippingLine.setLastUpdateUserId(PrincipalUtils.getAccountId());
        dao.save("ShippingLineMapper.insert", shippingLine);
        saveDetail(shippingLine.getId(), shippingLineDto);
        // 保存操作日志
        Map<String, Object> dataBackup = new HashMap<>();
        dataBackup.put("ADD_SHIPPINGLINE", shippingLine);
        PrincipalLogUtils.addOperationLog(ModuleNames.BIZ, ModuleNames.BIZ_SHIPPINGLINE, UserActions.ADD, "新建海运航线",
                dataBackup);
        return shippingLine.getId();
    }


    private void saveDetail(Integer shippingLineId, ShippingLineDto shippingLineDto) {
        if (!CollectionUtils.isEmpty(shippingLineDto.getPorts())) {
            final Integer[] i = {1};
            shippingLineDto.getPorts().forEach(item -> {
                Port port = portService.findShortById(item.getPortId());
                if (StringUtils.isEmpty(port.getCountryId())) {
                    throw Exceptions.bizException(ErrorCodes.ERROR_ARGUMENT_EMPTY, "port.countryId");
                }
                if (StringUtils.isEmpty(port.getCityId())) {
                    throw Exceptions.bizException(ErrorCodes.ERROR_ARGUMENT_EMPTY, "port.cityId");
                }

                item.setShippingLineId(shippingLineId);
                item.setOrdinal(i[0]++);
            });
            shippingLineDetailService.save(shippingLineDto.getPorts());
        }
    }


    @Override
    public int update(Integer id, ShippingLineDto shippingLineDto) {
        ShippingLine shippingLineExist = findSimpleById(id);
        if (shippingLineExist.getIsDeleted()) {
            throw Exceptions.bizException(ErrorCodes.ERROR_MODEL_HAS_DELETED, id);
        }
        ShippingLine shippingLine = new ShippingLine();
        EntityUtils.copyPropertiesIgnoreNull(shippingLineDto, shippingLine);
        // 检查数据不能重复
        checkCode(shippingLine.getCode(), id);
        shippingLine.setLastUpdateUserId(PrincipalUtils.getAccountId());
        shippingLine.setId(id);
        dao.update("ShippingLineMapper.update", shippingLine);
        shippingLineDetailService.deleteByShippingLineId(id);
        saveDetail(id, shippingLineDto);
        // 保存操作日志
        Map<String, Object> dataBackup = new HashMap<>();
        dataBackup.put("UPDATE_SHIPPINGLINE", shippingLine);
        PrincipalLogUtils.addOperationLog(ModuleNames.BIZ, ModuleNames.BIZ_SHIPPINGLINE, UserActions.UPDATE, "修改海运航线",
                dataBackup);
        return id;
    }

    @Override
    public void checkName(String name, Integer id) {
        Map<String, Object> map = new HashMap<>();
        if(StringUtils.isEmpty(name.trim())){
          	 throw Exceptions.bizException(ErrorCodes.ERROR_ARGUMENT_EMPTY, "name");       	
           }
        map.put("name", name);
        map.put("id", id);
        ShippingLine shipExist = (ShippingLine) dao.findForObject("ShippingLineMapper.checkName", map);
        if (shipExist != null) {
            throw Exceptions.bizException(ErrorCodes.ERROR_BIZ_SHIPPINGLINE_NAME_EXIST);
        }
    }

    @Override
    public void checkCode(String code, Integer id) {
        Map<String, Object> map = new HashMap<>();
        if(StringUtils.isEmpty(code.trim())){
       	    throw Exceptions.bizException(ErrorCodes.ERROR_ARGUMENT_EMPTY, "code");       	
         }
        map.put("code", code);
        map.put("id", id);
        ShippingLine shipExist = (ShippingLine) dao.findForObject("ShippingLineMapper.checkCode", map);
        if (shipExist != null) {
            throw Exceptions.bizException(ErrorCodes.ERROR_BIZ_SHIPPINGLINE_CODE_EXIST);
        }
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED)
    public void deleteByIds(List<Integer> ids) {
        dao.update("ShippingLineMapper.deleteByIds", ids);
        // 保存操作日志
        Map<String, Object> dataBackup = new HashMap<>();
        dataBackup.put("DELETE_SHIPPINGLINE", ids);
        PrincipalLogUtils.addOperationLog(ModuleNames.BIZ, ModuleNames.BIZ_SHIPPINGLINE, UserActions.DELETE, "删除海运航线",
                dataBackup);

    }

    @Override
    public ShippingLineDto findById(int id) {
        ParamData pd = new ParamData();
        pd.put("id", id);
        ShippingLine shippingLine = (ShippingLine) dao.findForObject("ShippingLineMapper.findById", pd);
        ShippingLineDto shippingLineDto = new ShippingLineDto();
        BeanUtils.copyProperties(shippingLine, shippingLineDto);
        getShippingLineName(id, shippingLineDto);

        Map<String, String> sysMapDicts = sysDicttService.findMapByCatalog("biz.linetype.base");
        shippingLineDto.setTypeName(sysMapDicts.get(shippingLine.getType()));
        return shippingLineDto;
    }


    @Override
    public ResultDto findShippingLineListPage(QueryParams params) {
        ParamData pd = this.convertQueryParams(params);
        // 调用方法查询数据
        List<ShippingLine> list = dao.findForList("ShippingLineMapper.shippingLineListPage", pd, ShippingLine.class);
        List<ShippingLineDto> dtos = new ArrayList<>();
        if (!CollectionUtils.isEmpty(list)) {

            list.forEach(shippingLine -> {
                ShippingLineDto dto = new ShippingLineDto();
                BeanUtils.copyProperties(shippingLine, dto);

                Map<String, String> sysMapDicts = sysDicttService.findMapByCatalog("biz.linetype.base");
                dto.setTypeName(sysMapDicts.get(dto.getType()));
                getShippingLineName(shippingLine.getId(), dto);
                dtos.add(dto);
            });
            for (ShippingLineDto dto : dtos) {
                List<ShippingLineDetailDto> details = dto.getPorts();

                if (!CollectionUtils.isEmpty(details)) {
                    dto.setStartName(details.get(0).getPortName());
                    dto.setStartEnglishName(details.get(0).getPortEnglishName());
                    if (details.size() >= 2) {
                        dto.setEndName(details.get(details.size() - 1).getPortName());
                        dto.setEndEnglishName(details.get(details.size()-1).getPortEnglishName());
                    }
                    List<String> portNames = EntityUtils.getStringPropListFromBeans(details, "portName");
                    if (portNames.size() > 0) {
                        dto.setStopOverName(StringUtils.arrayToDelimitedString(portNames.toArray(), "-"));
                    }
                    List<String> portEnNames = EntityUtils.getStringPropListFromBeans(details, "portEnglishName");
                    if (portEnNames.size() > 0) {
                        dto.setStopOverEnglishName(StringUtils.arrayToDelimitedString(portEnNames.toArray(), "-"));
                    }
                }
            }
        }
        QResultDto dto = new QResultDto();
        dto.setData(dtos);
        dto.setPagination(pd.getPagination());
        return dto;
    }

    private void getShippingLineName(Integer shippingLineId, ShippingLineDto dto) {
        if (shippingLineId != null) {
            List<ShippingLineDetail> shippingLineDetails = shippingLineDetailService.findByShippingLineId(shippingLineId);
            if (!CollectionUtils.isEmpty(shippingLineDetails)) {
                List<Integer> portIds = EntityUtils.getIntPropListFromBeans(shippingLineDetails, "portId");
                List<PortDto> ports = portService.findByPortIds(portIds);
                Map<String, PortDto> portDtoMap = EntityUtils.getStringKeyMapFromBeans(ports, "id");
                //List<ShippingLineDetailDto> dtos = new ArrayList<>();
                shippingLineDetails.forEach(shippingLineDetail -> {
                    ShippingLineDetailDto detailDto = new ShippingLineDetailDto();
                    BeanUtils.copyProperties(shippingLineDetail, detailDto);
                    detailDto.setPortName(portDtoMap.get(shippingLineDetail.getPortId() + "").getName());
                    detailDto.setPortEnglishName(  portDtoMap.get(shippingLineDetail.getPortId() + "").getEnglishName());
                    dto.getPorts().add(detailDto);
                });

            }

        }
    }

    /**
     * 根据shipId查询海运航线信息
     *
     * @param ShipId ShipId
     * @return ShippingLine
     */
    @Override
    public ShippingLine findSimpleById(int ShipId) {
        ParamData pd = new ParamData();
        pd.put("id", ShipId);
        return (ShippingLine) dao.findForObject("ShippingLineMapper.findById", pd);
    }

    /**
     * 根据条件分页查询海运航线短接口
     *
     * @param params params
     * @return ResultDto
     */
    @Override
    public ResultDto findShippingLineShortListPage(QueryParams params) {
        ParamData pd = this.convertQueryParams(params);
        // 调用方法查询数据
        List<ShippingLine> list = dao.findForList("ShippingLineMapper.shippingLineShortListPage", pd, ShippingLine.class);
        QResultDto dto = new QResultDto();
        dto.setData(list);
        dto.setPagination(pd.getPagination());
        return dto;
    }


    @Override
    protected String getMapperNamespace() {
        return "ShippingLineMapper";
    }
}
